// Package meth upgrade_handler.go
package meth

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"sync"
	"time"
)

// 请求结构体
type UpgradeRequest struct {
	Devices []string `json:"devices"`
}

// 响应结构体
type UpgradeResponse struct {
	Total   int            `json:"total"`
	Success int            `json:"success"`
	Failed  int            `json:"failed"`
	Details []DeviceResult `json:"details"`
}

type DeviceResult struct {
	IP     string `json:"ip"`
	Status string `json:"status"`
	Error  string `json:"error,omitempty"`
}

// 全局复用连接池
var clientPool = sync.Pool{
	New: func() interface{} {
		return &http.Client{
			Transport: &http.Transport{
				MaxIdleConns:        100,
				IdleConnTimeout:     90 * time.Second,
				DisableKeepAlives:   false,
				MaxIdleConnsPerHost: 32,
			},
			Timeout: requestTimeout,
		}
	},
}

// 并发控制配置
const (
	maxConcurrent  = 64               // 最大并发数
	requestTimeout = 10 * time.Second // 单个请求超时
)

func HandleUpgrade(w http.ResponseWriter, r *http.Request) {
	// 解析请求
	var req UpgradeRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, `{"error": "Invalid request format"}`, http.StatusBadRequest)
		return
	}

	// 初始化响应
	result := UpgradeResponse{
		Total:   len(req.Devices),
		Details: make([]DeviceResult, 0, len(req.Devices)),
	}

	// 创建带超时的上下文
	ctx, cancel := context.WithTimeout(r.Context(), 5*time.Minute)
	defer cancel()

	// 并发控制
	sem := make(chan struct{}, maxConcurrent)
	var wg sync.WaitGroup
	var mu sync.Mutex

	for _, ip := range req.Devices {
		wg.Add(1)
		sem <- struct{}{}

		go func(deviceIP string) {
			defer func() {
				<-sem
				wg.Done()
			}()

			// 执行设备升级
			_, err := upgradeDevice(ctx, deviceIP)

			// 记录结果
			mu.Lock()
			defer mu.Unlock()

			if err != nil {
				result.Failed++
				result.Details = append(result.Details, DeviceResult{
					IP:     deviceIP,
					Status: "failed",
					Error:  err.Error(),
				})
			} else {
				result.Success++
				result.Details = append(result.Details, DeviceResult{
					IP:     deviceIP,
					Status: "success",
				})
			}
		}(ip)
	}

	wg.Wait()

	// 返回响应
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(result)
}

// 单个设备升级逻辑
func upgradeDevice(ctx context.Context, ip string) (string, error) {
	// 构造请求体
	payload := map[string]int{"flag": 1}
	jsonData, _ := json.Marshal(payload)

	// 创建带超时的请求
	req, err := http.NewRequestWithContext(
		ctx,
		"POST",
		fmt.Sprintf("http://%s/check-firmware-upgrade", ip),
		bytes.NewBuffer(jsonData),
	)
	if err != nil {
		return "", fmt.Errorf("创建请求失败: %w", err)
	}
	req.Header.Set("Content-Type", "application/json")

	// 发送请求
	client := clientPool.Get().(*http.Client)
	defer clientPool.Put(client)
	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("请求失败: %w", err)
	}
	defer resp.Body.Close()

	// 验证响应状态码
	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("设备返回错误状态码: %d", resp.StatusCode)
	}

	return "升级指令已接收", nil
}
